#region Using

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;

using Gizmox.WebGUI.Common;
using Gizmox.WebGUI.Forms;
using System.IO;
using System.Text.RegularExpressions;
using Gizmox.WebGUI.Common.Gateways;

#endregion

namespace TVC.Modules.CustomControl
{
    public partial class SelectFileDialog : Form
    {
        private List<Path> mPath = new List<Path>();
        private string returnPath = null;
        private string title = null;
        private string category = null;

        public string ReturnPath
        {
            get { if (returnPath == null) return null; else return returnPath; }
        }
        public string ReturnTitle
        {
            get { if (title == null) return null; else return title; }
        }
        public string ReturnCategory
        {
            get { if (category == null) return null; else return category; }
        }
        string _trans_type;
        public SelectFileDialog(List<Path> _mPath, string trans_type)
        {
            InitializeComponent();
            this.mPath = _mPath;
            listView1.SmallImageList = imageList1;
            _trans_type = trans_type;
        }
        private void InitTreeView(DirInfo dirinfo)
        {

            BindDirectory(dirinfo);
        }
        private void AddDirToNode(TreeNode n, DirInfo dirinfo)
        {
            var rootNode = new TreeNode(dirinfo.Path.View) { Tag = dirinfo };
            rootNode.Expand();
            n.Nodes.Add(ListDirectoryToNode(rootNode));
            //InitAll(dirinfo);
        }
        private void AddDirToNode(TreeView n, DirInfo dirinfo)
        {
            var rootNode = new TreeNode(dirinfo.Path.View) { Tag = dirinfo };
            rootNode.Expand();
            n.Nodes.Add(ListDirectoryToNode(rootNode));
            //InitAll(dirinfo);
        }
        private void BindDirectory(DirInfo dirinfo)
        {
            ListDirectoryListView(dirinfo);
            bindTextBox(dirinfo);
            highlightNode(treeView1.Nodes, dirinfo);
        }
        private bool dirCanAccess(DirectoryInfo dir)
        {
            bool isHidden = ((dir.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden);

            bool isSystem = ((dir.Attributes & FileAttributes.System) == FileAttributes.System);

            if (isHidden == true || isSystem == true)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        private bool fileCanAccess(FileInfo file)
        {
            bool isHidden = ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden);

            bool isSystem = ((file.Attributes & FileAttributes.System) == FileAttributes.System);
            if (isHidden == true || isSystem == true)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        private TreeNode ListDirectoryToNode(TreeNode Node)
        {
            Node.Nodes.Clear();
            Node.ImageKey = "Folder.gif";
            var rootDirectory = ((DirInfo)(Node.Tag));
            try
            {
                foreach (DirectoryInfo dir in rootDirectory.Dir.GetDirectories())
                {
                    if (dirCanAccess(dir))
                    {
                        var curNode = new TreeNode(dir.Name) { Tag = new DirInfo(dir, rootDirectory.Path) };
                        curNode.ImageKey = "Folder.gif";
                        try
                        {
                            foreach (DirectoryInfo childDir in dir.GetDirectories())
                            {
                                if (dirCanAccess(childDir))
                                {
                                    var childNode = new TreeNode(childDir.Name) { Tag = new DirInfo(childDir, rootDirectory.Path) };
                                    childNode.ImageKey = "Folder.gif";
                                    curNode.Nodes.Add(childNode);
                                }
                            }
                            Node.Nodes.Add(curNode);
                        }
                        catch
                        {

                        }
                    }
                }
            }
            catch { };
            return Node;
        }


        private void ListDirectoryListView(DirInfo dirinfo)
        {
            listView1.Items.Clear();

            if (checkIsRoot(dirinfo))
            {
                var directory = dirinfo.Dir;
                try
                {
                    foreach (var dir in directory.GetDirectories())
                    {
                        if (dirCanAccess(dir))
                        {
                            ListViewItem item = new ListViewItem(dir.Name);
                            item.SubItems.Add("Folder");
                            item.ImageKey = "Folder.gif";
                            item.Tag = new DirInfo(dir, dirinfo.Path);
                            listView1.Items.Add(item);
                        }

                    }
                }
                catch { };
                try
                {
                    foreach (var file in directory.GetFiles())
                    {
                        if (fileCanAccess(file))
                        {
                            ListViewItem item = new ListViewItem(file.Name);
                            item.SubItems.Add(file.Extension.ToString().Replace(".", "").ToUpper());
                            item.SubItems.Add(dirinfo.Path.ConvertToVitualPath(file.FullName));
                            item.Tag = new DirInfo(file, dirinfo.Path);
                            item.ImageKey = "24X24.sales.png";
                            listView1.Items.Add(item);
                        }
                    }
                }
                catch { };
            }
            else
            {

                foreach (Path path in dirinfo.Path.MPath)
                {
                    ListViewItem item = new ListViewItem(path.Name);
                    item.SubItems.Add("Folder");
                    item.ImageKey = "Folder.gif";
                    item.Tag = new DirInfo(new DirectoryInfo(dirinfo.Path.Url + path.Name), dirinfo.Path);
                    listView1.Items.Add(item);
                }
            }

        }
        //DirInfo oldPathInfo = null;
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            SelectNode();

        }

        private void SelectNode()
        {
            DirInfo dirInfo;
            dirInfo = ((DirInfo)(treeView1.SelectedNode.Tag));
            if (checkIsRoot(dirInfo))
            {

                treeView1.SelectedNode = ListDirectoryToNode(treeView1.SelectedNode);
                treeView1.SelectedNode.Expand();
                bindTextBox(dirInfo);
                this.ListDirectoryListView(dirInfo);
            }
            else
            {
                treeView1.SelectedNode.Expand();
                bindTextBox(dirInfo);
                this.ListDirectoryListView(dirInfo);
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (listView1.SelectedItem != null)
            {
                if (listView1.SelectedItem.SubItems[1].ToString() != "Folder")
                {
                    DirInfo dirinfo = ((DirInfo)listView1.SelectedItem.Tag);
                    //oldPathInfo = dirinfo;                    
                    this.returnPath = dirinfo.Path.ConvertToVitualPath(dirinfo.File.FullName);
                    MainForm.pathinfo = returnPath;
                    this.title = dirinfo.File.Name;
                    this.category = dirinfo.File.Extension.ToString().Replace(".", "").ToUpper();
                    DialogResult = DialogResult.OK;
                    Close();
                }
            }
        }
        private void ofd_FileOk(object sender, CancelEventArgs e)
        {

            OpenFileDialog objOFD = sender as OpenFileDialog;
            if (objOFD == null)
            {
                return;
            }
            Gizmox.WebGUI.Common.Resources.FileHandle objFile = null;
            if (objOFD.Files[0] == null || !(objOFD.Files[0] is Gizmox.WebGUI.Common.Resources.FileHandle))
            {
                return;
            }
            objFile = objOFD.Files[0] as Gizmox.WebGUI.Common.Resources.FileHandle;
            string filename = ((DirInfo)(textBox1.Tag)).Dir.FullName + @"\" + objFile.OriginalFileName;

            objFile.SaveAs(filename);
            BindDirectory(((DirInfo)(textBox1.Tag)));


        }
        private TreeNode FindRootNode(TreeNode treeNode)
        {
            while (treeNode.Parent != null)
            {
                treeNode = treeNode.Parent;
            }
            return treeNode;
        }
        private void button2_Click(object sender, EventArgs e)
        {
            Close();



        }
        private void listView1_DoubleClick(object sender, EventArgs e)
        {
            if (listView1.SelectedItem != null)
            {
                if (listView1.SelectedItem.SubItems[1].ToString() == "Folder")
                {
                    DirInfo selectDir = ((DirInfo)(listView1.SelectedItem.Tag));
                    string selectPath = selectDir.Dir.FullName;
                    bindTextBox(selectDir);
                    highlightNode(treeView1.Nodes, selectDir);
                    ListDirectoryListView(selectDir);
                }
                else
                {
                    DirInfo dirinfo = ((DirInfo)listView1.SelectedItem.Tag);
                    //oldPathInfo = dirinfo;
                    this.returnPath = dirinfo.Path.ConvertToVitualPath(dirinfo.File.FullName);
                    MainForm.pathinfo = returnPath;
                    this.title = dirinfo.File.Name;
                    this.category = dirinfo.File.Extension.ToString().Replace(".", "").ToUpper();
                    DialogResult = DialogResult.OK;
                    Close();
                }
            }
        }
        public void bindTextBox(DirInfo dirinfo)
        {
            if (checkIsRoot(dirinfo))
            {
                textBox1.Tag = dirinfo;
                textBox1.Text = dirinfo.Path.ConvertToVitualPath(dirinfo.Dir.FullName);
            }
            else
            {
                textBox1.Tag = dirinfo;
                textBox1.Text = dirinfo.Path.View;
            }
        }
        private void highlightNode(TreeNodeCollection nodes, DirInfo tag)
        {
            foreach (TreeNode node in nodes)
            {
                if (checkIsRoot(tag) && checkIsRoot((DirInfo)node.Tag))
                    if (((DirInfo)(node.Tag)).Dir.FullName.Equals(tag.Dir.FullName) && ((DirInfo)(node.Tag)).Path.Equals(tag.Path))
                    {
                        treeView1.SelectedNode = node;
                        ListDirectoryToNode(node);
                    }
                highlightNode(node.Nodes, tag);
            }
        }
        private bool checkIsRoot(DirInfo info)
        {
            return !info.Isroot;
        }
        private void uploadHereClick(object sender, EventArgs e)
        {
            if (checkIsRoot((DirInfo)textBox1.Tag))
            {
                OpenFileDialog of = new OpenFileDialog();
                of.ShowDialog();
                of.FileOk += new CancelEventHandler(ofd_FileOk);
            }
            else
            {
                MessageBox.Show("Can not upload file here!");
            }
        }
        private void backClick(object sender, EventArgs e)
        {
            TreeNode node = treeView1.SelectedNode;
            if (node.Parent != null)
            {
                treeView1.SelectedNode = node.Parent;
                DirInfo dirInfo = (DirInfo)node.Parent.Tag;
                BindDirectory(dirInfo);
            }
        }

        private void newFolder(object sender, EventArgs e)
        {
            if (checkIsRoot((DirInfo)textBox1.Tag))
            {
                EditDialog ed = new EditDialog("New folder");
                ed.FormClosed += (form, frmArgs) =>
                {
                    if (((EditDialog)form).DialogResult == DialogResult.OK)
                    {
                        DirInfo pDir = (DirInfo)textBox1.Tag;
                        string newFolderpath = pDir.Dir.FullName + @"\" + ed.name;
                        if (Directory.Exists(newFolderpath))
                        {
                            MessageBox.Show("This folder already exist!");
                        }
                        else
                        {
                            Directory.CreateDirectory(newFolderpath);
                            BindDirectory(pDir);
                        }
                    }
                };
                ed.ShowDialog();
            }
            else
            {
                MessageBox.Show("Can not create folder here!");
            }

        }
        private void refresh(object sender, EventArgs e)
        {
            DirInfo dirInfo = ((DirInfo)(treeView1.SelectedNode.Tag));
            if (checkIsRoot(dirInfo))
            {
                treeView1.SelectedNode.Nodes.Clear();
                treeView1.SelectedNode = ListDirectoryToNode(treeView1.SelectedNode);
                treeView1.SelectedNode.Expand();
                bindTextBox(dirInfo);
                this.ListDirectoryListView(dirInfo);
            }
        }

        private void downloadFile(object sender, EventArgs e)
        {
            if (listView1.SelectedItem != null && listView1.SelectedItem.SubItems[1].ToString() != "Folder")
            {

                DirInfo file = ((DirInfo)(listView1.SelectedItem.Tag));
                if (File.Exists(file.File.FullName))
                {
                    string fileName = file.File.FullName;
                    DownloadGateway myDownload = new DownloadGateway(fileName);

                    //myDownload.ContentType = "application/vnd.ms-excel";
                    myDownload.StartDownload(this);
                }

            }
        }

        private void SelectFileDialog_Load(object sender, EventArgs e)
        {
            if (mPath.Count > 0)
            {
                foreach (Path path in mPath)
                {
                    try
                    {
                        if (CheckExists(path.Url))
                        {
                            DirectoryInfo rootDir = new DirectoryInfo(path.Url);
                            DirInfo dirinfo = new DirInfo(rootDir, path);

                            var rootNode = new TreeNode(dirinfo.Path.View) { Tag = dirinfo };
                            //rootNode.Expand();
                            treeView1.Nodes.Add(ListDirectoryToNode(rootNode));
                            //if (_currentView != null)
                            //{
                            //    if (BindCurrent(_currentView) == null) BindDirectory(dirinfo);
                            //}
                            //else BindDirectory(dirinfo);

                            //InitTreeView(dirinfo);
                        }
                        else if (path.Isroot)
                        {
                            var rootNode = new TreeNode(path.View) { Tag = new DirInfo(path.Isroot, path) };
                            foreach (Path subpath in path.MPath)
                            {
                                //DirectoryInfo rootDir = new DirectoryInfo(subpath.Url);
                                //DirInfo dirinfo = new DirInfo(rootDir, subpath);
                                //AddDirToNode(rootNode, dirinfo);

                                TreeNode treenode = new TreeNode(subpath.Name) { Tag = new DirInfo(new DirectoryInfo(subpath.Url), path) };
                                treenode.ImageKey = "Folder.gif";
                                rootNode.Nodes.Add(treenode);

                            }
                            rootNode.ImageKey = "Folder.gif";
                            treeView1.Nodes.Add(rootNode);

                            //if (_currentView != null)
                            //{
                            //    BindCurrent(_currentView);
                            //}
                        }
                    }
                    catch (Exception ex) { throw new Exception("[" + path.Url + "]" + ex.Message); }

                }
                if (_currentView != null)
                {
                    if (BindCurrent(_currentView) == null) treeView1.SelectedNode = treeView1.TopNode;
                }
                else treeView1.SelectedNode = treeView1.TopNode;
            }
        }

        private bool BindCurrent(string curView)
        {
            if (curView == null) return false;
            DirInfo n = GotoPath(curView, treeView1);
            //if (n != null) BindDirectory(n);

            if (n != null) return true;
            return false;

        }

        private DirInfo GotoPath(string curView, object root)
        {
            TreeNodeCollection nodes = null;
            if (root is TreeNode) nodes = ((TreeNode)root).Nodes;
            else if (root is TreeView) nodes = ((TreeView)root).Nodes;

            if (nodes == null) return null;

            for (int i = 0; i < nodes.Count; i++)
            {
                TreeNode n = nodes[i];
                if (GetView(((DirInfo)n.Tag)) == curView)
                {
                    treeView1.SelectedNode = n;
                    return (DirInfo)n.Tag;
                }

                if (IsParent(curView, GetView((DirInfo)n.Tag)))
                {
                    if (n.Nodes.Count == 0) n = ListDirectoryToNode(n);
                    return GotoPath(curView, n);
                }
            }
            return null;
        }

        private bool IsParent(string child, string parent)
        {
            string p = GetParent(child);
            while (p != null && p != string.Empty)
            {
                if (p == parent || p + "\\" == parent) return true;
                p = GetParent(p);
            }
            return false;
        }

        public static string GetParent(string child)
        {
            if (string.IsNullOrEmpty(child)) return string.Empty;

            return Regex.Match(child.Trim(), @"(.|\s)+(?=[\/;\\])").ToString().Trim();
        }

        private string GetView(DirInfo dirInfo)
        {
            if (checkIsRoot(dirInfo))
            {
                return dirInfo.Path.ConvertToVitualPath(dirInfo.Dir.FullName);
            }
            return dirInfo.Path.View;
        }

        private static bool CheckExists(string path)
        {
            Func<bool> func = () => Directory.Exists(path);
            System.Threading.Tasks.Task<bool> task = new System.Threading.Tasks.Task<bool>(func);
            task.Start();
            if (task.Wait(1000))
            {
                return task.Result;
            }
            else
            {
                // Didn't get an answer back in time be pessimistic and assume it didn't exist
                return false;
            }
        }

        string _currentView = null;

        internal void SetCurrentPath(string currentView)
        {
            _currentView = currentView;
        }

        private void SelectFileDialog_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (treeView1.SelectedNode != null)
            {
                MainForm.SetCurrentDocLink(_trans_type, textBox1.Text);
            }
            else MainForm.SetCurrentDocLink(_trans_type, null);
        }

        private void treeView1_AfterExpand(object sender, TreeViewEventArgs e)
        {
            SelectNode();
        }
    }

    public class DirInfo
    {
        FileInfo file;

        public FileInfo File
        {
            get { return file; }
            set { file = value; }
        }
        bool isroot = false;

        public bool Isroot
        {
            get { return isroot; }
            set { isroot = value; }
        }
        DirectoryInfo dir;
        public DirInfo()
        {
        }
        public DirInfo(DirectoryInfo dir, Path path)
        {
            this.dir = dir;
            this.path = path;

        }

        public DirInfo(bool isroot, Path path)
        {
            this.isroot = isroot;
            this.path = path;

        }

        public DirInfo(FileInfo file, Path path)
        {
            this.file = file;
            this.path = path;
        }
        public DirectoryInfo Dir
        {
            get { return dir; }
            set { dir = value; }
        }
        Path path;

        public Path Path
        {
            get { return path; }
            set { path = value; }
        }

        internal bool IsParent(DirInfo dirInfo)
        {
            DirectoryInfo p = this.Dir.Parent;
            if (p == null)
            {
                //dirInfo.Dir.FullName
            }
            else
            {
                while (p != null)
                {
                    if (dirInfo.Dir.FullName == p.FullName) return true;
                    p = p.Parent;
                }
            }
            return false;

        }
    }


}